/*!
 * WannaCry扫描控制器
 *
 * 版权所有 2017 陈学芹 联系方式: 7219530@qq.com
 *
 * 本软件在GNU LGPL-V2.1协议下发布，欢迎使用.
 */
var express = require('express');
var router = express.Router();
require('./common');
var execOptions = {title:"端口扫描" };
var setupOptions = {title:"端口规格配置" };
var NmapManagerFactory = require('../nmap/nmap-manager');
var Nmap = require('../nmap/nmap').nodenmap;
var ConfigManager = require('../lib/config');
var manager;
var _ = require('lodash');
var logger = require('../lib/logger');
const util = require('util');
const Beian = require('../lib/beian');
const EventEmitter = require('events');

NmapManagerFactory.setHome(ConfigManager.getNmapStorageDir());
manager = NmapManagerFactory.getManager();

function processResult(locals, results) {
  var resultForMan = {};
  var dangerPorts = ["135", "137", "138", "139", "445"];

  var result = results[0];
  resultForMan.host = result.host;
  resultForMan.safe = true;
  //当135,137,138,139,445端口均未打开时，则判定为安全
  var openPorts = result.openPorts;
  for (var i=0; i<openPorts.length; i++) {
    var p = openPorts[i];
    if (p.state.state != 'open')
      continue;
    if (dangerPorts.indexOf(p.port.portid) != -1)
      resultForMan.safe = false;
  }
  openPorts.sort((a, b)=> {
    return parseInt(a.port.portid) - parseInt(b.port.portid);
  });

  //将危险端口标记出来
  var portsStr = '';
  for (var i=0; i<openPorts.length; i++) {
    var p = openPorts[i];
    if (dangerPorts.indexOf(p.port.portid) != -1)
      p.state.danger = true;
    if (p.state.state == 'open') {
      portsStr += p.port.portid+',';
    }
  }
  resultForMan.ports = openPorts;
  logger.info("host:%s os:%s, safe:%s, open ports:%s", locals.reqip,
    locals.useragent.os, resultForMan.safe, portsStr);
}

router.post('/api/cry', function(req, res){
  //TODO:处理参数异常情况
  var target = null;
  if (!req.body.target || req.body.target == 'me') {
    target = res.locals.reqip;
  }else {
    target = req.body.target;
  }
  var myEmitter = new EventEmitter();
  var completeFlag = {
    nmap: false,
    beian: false
  };

  function completeFunc(eventName) {
    if (eventName == 'NmapComplete') {
      completeFlag.nmap = true;
    }

    if (eventName == 'BeianComplete') {
      completeFlag.beian = true;
    }
    logger.debug("complete %s", eventName);
  }
  myEmitter.on('NmapComplete', completeFunc);
  myEmitter.on('BeianComplete', completeFunc);

  logger.debug("start cry detect on host %s", target);
  var scan = new Nmap.NmapScan(target, "-Pn");
  var result = manager.addResult(scan);
  scan.startScan();
  scan.on('complete', function (data) {
    manager.updateResult( result, data);
    logger.debug("scan complete %s", util.inspect(data, {depth: null}));
    processResult(res.locals, data);
    myEmitter.emit('NmapComplete', 'NmapComplete');
  });
  //nmap调用可能失败，故在调用方必须增加容错处理
  scan.on('error', function (data) {
    //manager.updateResult( result, data)
  });

  var beian = new Beian(target);
  beian.startScan();
  beian.on('complete', function (data) {
    manager.updateBeianResult( result, data);
    myEmitter.emit('BeianComplete', 'BeianComplete');
    logger.debug("scan complete %s", util.inspect(data, {depth: null}));
  });

  //必须手工设定，否则返回304 Not Modified
  res.status(200).json(result);
  logger.debug("result %s", util.inspect(result, {depth: null}));
});

router.get('/api/cry', function(req, res){
  logger.debug("query id %s", req.query.id);
  var result = manager.getResultWithDetail(req.query.id);
  res.status(200).json(result);
});

module.exports = router;
